package com.project.dao.impl;

import java.lang.reflect.Field;
import java.sql.*;
import java.time.LocalDate;
import java.util.*;

/**
 * 所有DAO的父类
 */
public class BaseDao {
    /**连接*/
    protected Connection con;
    /**SQL语句执行对象*/
    protected PreparedStatement ps;
    /**结果集*/
    protected ResultSet rs;

    /**
     * 建立连接
     */
    public void setConnection(){
        try {
            Class.forName("com.mysql.jdbc.Driver");
            con = DriverManager.getConnection(
                    "jdbc:mysql://localhost:6789/shopDB?characterEncoding=utf-8"
                        ,"root","lovo");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭连接
     */
    public void closeConnection(){
        try {
            if(rs != null) {
                rs.close();
            }
            if(ps != null) {
                ps.close();
            }
            if(con != null) {
                con.close();
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    /**
     * 更新数据库的数据
     * @param sql 执行的SQL语句
     * @param valueArray 值列表
     */
    public  void updateData(String sql,Object... valueArray){
        this.setConnection();

        try {
            ps = con.prepareStatement(sql);
            for(int i=0;i<valueArray.length;i++){
                ps.setObject(i+1,valueArray[i]);
            }

            ps.executeUpdate();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally{
            this.closeConnection();
        }
    }

    /**
     * 查询操作
     * @param sql 执行SQL语句
     * @param beanClass 集合中存放实体类的类模版
     * @param valueArray 值列表
     * @return 查询集合
     */
    public List  find(String sql,Class beanClass,Object... valueArray){
        List list  = new ArrayList();
        this.setConnection();
        try {
            ps = con.prepareStatement(sql);
            for(int i=0;i<valueArray.length;i++){
                ps.setObject(i+1,valueArray[i]);
            }

            rs = ps.executeQuery();
//            while(rs.next()){
//                //调用实体类的无参构造方法产生对象
//                Object beanObj = beanClass.getConstructor().newInstance();
//                //得到实体类中所有的属性列表
//                Field[] fArray = beanClass.getDeclaredFields();
//                for(Field f : fArray){
//                    try {
//                        //从结果集中得到当前属性的值
//                        Object value = rs.getObject(f.getName());
//                        if (f.getType() == LocalDate.class) {
//                            value = LocalDate.parse(value.toString());
//                        }
//
//                        //去掉修饰符检查
//                        f.setAccessible(true);
//                        //将beanObj对象的f属性，设置为value值
//                        f.set(beanObj, value);
//                    }catch (Exception e){
//                        continue;
//                    }
//
//                }
//                list.add(beanObj);
//            }

            //得到结果集信息对象
            ResultSetMetaData rm =  rs.getMetaData();
            //得到查询列数
            int columnCount = rm.getColumnCount();

            while(rs.next()){
                Object beanObj = beanClass.getConstructor().newInstance();
                for(int i=1;i<=columnCount;i++){
                    //得到指定位置列名
                    String columnName = rm.getColumnName(i);
                    //根据列名，得到结果集的值
                    Object value = rs.getObject(columnName);
                    if(value instanceof java.sql.Date){
                        value = LocalDate.parse(value.toString());
                    }
                    //根据属性名，得到属性对象
                    Field f = beanClass.getDeclaredField(columnName);
                    f.setAccessible(true);
                    //给对象中指定属性赋值。
                    f.set(beanObj,value);
                }
                list.add(beanObj);
            }

        } catch (Exception throwables) {
            throwables.printStackTrace();
        }finally{
            this.closeConnection();
        }


        return list;
    }

//    public static void main(String[] args) {
//        updateData("",new Object[]{90,"333","333"});
//        updateData("",90,"333","333");
//    }
}
